
#include "driver.h"
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <iostream>
Driver driver;

Driver::Driver():LitSW_L(7,2),LitSW_R(7,3)
{
    // LitSW = new Limitation;

    std::cout << "Driver all initialized" <<std::endl;
}

Driver::~Driver()
{
    std::cout << "Driver dead" <<std::endl;

}


Step::Step()
{
    // Export PWM channel
    writeToFile("/sys/class/pwm/pwmchip4/export", "0");    

    // Export GPIO port
    std::cout << "Dir_gpio_s:" << 477 << std::endl;
    writeToFile("/sys/class/gpio/export", "477");
    writeToFile("/sys/class/gpio/gpio477/direction", "out");
    writeToFile("/sys/class/gpio/gpio477/value", "1"); 
    std::cout << "Step started." << std::endl;
}
Step::~Step()
{
    enable(0);
}
int Step::setspeed(int speed)
{
    std::cout << "Step speed:" << std::to_string(speed).c_str() <<std::endl;
    writeToFile("/sys/class/pwm/pwmchip4/pwm0/period", std::to_string(speed).c_str()); //  ms
    return writeToFile("/sys/class/pwm/pwmchip4/pwm0/duty_cycle", std::to_string(speed/2).c_str()); // 50% of period
}
int Step::enable(bool enable)
{
    std::cout << "Step enable:" << std::to_string(enable).c_str() <<std::endl;
    return writeToFile("/sys/class/pwm/pwmchip4/pwm0/enable", std::to_string(enable).c_str()); // 50% of period
}
int Step::setdir(bool dir)
{
    std::cout << "Step setdir:" << std::to_string(!dir).c_str() <<std::endl;
    return writeToFile("/sys/class/gpio/gpio477/value", std::to_string(!dir).c_str()); // 50% of period
}
Servo::Servo()
{
    // Export PWM channel
    writeToFile("/sys/class/pwm/pwmchip3/export", "0");    
    // set poarlity normal
    writeToFile("/sys/class/pwm/pwmchip3/pwm0/polarity", "normal"); // 1 ms
    // Set period (in nanoseconds)
    writeToFile("/sys/class/pwm/pwmchip3/pwm0/period", "10000000"); // 1 ms
    // Set duty cycle (in nanoseconds)
    writeToFile("/sys/class/pwm/pwmchip3/pwm0/duty_cycle", "2500000"); // 50% of period
    // Enable PWM signal
    writeToFile("/sys/class/pwm/pwmchip3/pwm0/enable", "1");
    std::cout << "Servo started." << std::endl;
}

Servo::~Servo()
{
    writeToFile("/sys/class/pwm/pwmchip3/pwm0/enable", "0");
    std::cout << "Servo stoped." << std::endl;
}
int Servo::setspeed(int speed)
{
    std::cout << "speed:" << std::to_string(speed).c_str() <<std::endl;
    return writeToFile("/sys/class/pwm/pwmchip3/pwm0/duty_cycle", std::to_string(speed).c_str()); // 50% of period
}
Ledlight::Ledlight()
{
    // Export PWM channel
    writeToFile("/sys/class/pwm/pwmchip5/export", "0");    
    // Set period (in nanoseconds)
    writeToFile("/sys/class/pwm/pwmchip5/pwm0/period", "1000000"); // 1 ms
    // Set duty cycle (in nanoseconds)
    writeToFile("/sys/class/pwm/pwmchip5/pwm0/duty_cycle", "500000"); // 50% of period
    // Enable PWM signal
    writeToFile("/sys/class/pwm/pwmchip5/pwm0/enable", "1");
    std::cout << "Led started." << std::endl;
}
Ledlight::~Ledlight()
{
    writeToFile("/sys/class/pwm/pwmchip5/pwm0/enable", "0");
    std::cout << "Led ended." << std::endl;
}
int Ledlight::setbright(int brightness){
    std::cout << "LED setbright:" << std::to_string((int)((brightness/100.0)*1000000)).c_str() <<std::endl;
    return writeToFile("/sys/class/pwm/pwmchip5/pwm0/duty_cycle", std::to_string((int)((brightness/100.0)*1000000)).c_str()); // 50% of period
}
Limitation::Limitation(int chip_num, int line_num)
{
    // Construct the path for the GPIO chip based on chip_num
    std::string gpio_chip = "/dev/gpiochip" + std::to_string(chip_num);
    auto chip = gpiod::chip(gpio_chip);
    // Request the line as input with pull-down resistor enabled
    gpiod::line_request config;
    config.consumer = "Limitation";
    config.request_type = gpiod::line_request::DIRECTION_INPUT;
    config.flags = gpiod::line_request::FLAG_BIAS_PULL_UP;
    line_= chip.get_line(line_num);
    line_.request(config);

}

Limitation::~Limitation()
{
}


int Limitation::getLimitation()
{
    return line_.get_value();
}
int writeToFile(const std::string& path, const std::string& value) {
    std::ofstream file(path);
    if (!file.is_open()) {
        std::cerr << "Failed to open file: " << path << std::endl;
        return -1;
    }
    file << value;
    file.close();
    return 0;
}
